/**
 * 
 */
package com.gamex.findit.battle;

import java.net.InetSocketAddress;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelException;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipelineCoverage;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.gamex.findit.Constants;
import com.gamex.findit.service.BattleService;


/**
 * 소켓 서버
 * @author james
 *
 */
@Component
@ChannelPipelineCoverage("one")
public class BattleServer extends SimpleChannelHandler {
	
	private static final Logger logger = LoggerFactory.getLogger(BattleServer.class);
	
	@Autowired BattleService battleService;

	private Channel serviceChannel;
	private ExecutorService bossExecutor;
	private ExecutorService workerExecutor;

	public final void initBattleServer(){
		bossExecutor = Executors.newCachedThreadPool();
		workerExecutor = Executors.newCachedThreadPool();
		ChannelFactory channelFactory = new NioServerSocketChannelFactory(bossExecutor, workerExecutor);
		ServerBootstrap bootstrap = new ServerBootstrap(channelFactory);
		try {
			bootstrap.setPipelineFactory(new ServerPipelineFactory(battleService));
			bootstrap.setOption("child.tcpNoDelay", true);
			bootstrap.setOption("child.keepAlive", true);
			bootstrap.setOption("reuseAddress", true);
			serviceChannel = bootstrap.bind(new InetSocketAddress(Constants.SOCKET_PORT));
			
			logger.info("-------------------------------------------------");
			logger.info("battle socket server started");
			logger.info("-------------------------------------------------");
			
		} catch (ChannelException ex) {
			if (logger.isErrorEnabled()) {
				logger.error("PointPaymentServer binding failed on port " + Constants.SOCKET_PORT);
				ex.printStackTrace();
			}
			throw ex;
		} finally {
			bootstrap = null;
			channelFactory = null;
		}
	}

	public final void destroy(){
		
		try {
			if (serviceChannel != null)
				serviceChannel.unbind();
			if (workerExecutor != null) {
				workerExecutor.shutdownNow();
				workerExecutor.awaitTermination(0, TimeUnit.SECONDS);
			}

			if (bossExecutor != null) {
				bossExecutor.shutdownNow();
				bossExecutor.awaitTermination(1, TimeUnit.SECONDS);
			}
			
			logger.info("-------------------------------------------------");
			logger.info("battle server destroy...");
			logger.info("-------------------------------------------------");
			
		} catch (Exception e) {
		}
		
		
	}

}
